package org.jeecg.modules.simulator.model.line.station.station;

import lombok.Getter;
import lombok.Setter;
import org.jeecg.modules.simulator.jsonot.ODProbabilityApiInfo;
import org.jeecg.modules.simulator.jsonot.RouteStation;
import org.jeecg.modules.simulator.model.person.Person;
import org.jeecg.modules.simulator.model.person.path.PersonPath;

import java.util.*;

/**
 * @program: simulator-b20240918
 * @description:
 * @author: renzhg
 * @create: 2024-10-30 10:01
 **/
public class LoadHistoryPeriodTimePerson implements LoadPerson {

    @Getter
    @Setter
    Map<String, Person> outsidePersonMap = new HashMap<>();
    @Setter
    Map<String, List<RouteStation>> t80RouteHisMap;
    Map<String, Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfosMapmap = new HashMap<>();
    @Setter
    Map<String, PersonPath> route2PersonPathMap = new HashMap<>();

    @Setter
    @Getter
    //换乘站集合
    Map<String, TransferStation> transferStationMap = new HashMap<>();//换乘站集合

    @Getter
    @Setter
    Map<String, Station> stationNetMap = new HashMap<>();

    public LoadHistoryPeriodTimePerson(Map<String, Map<String, List<ODProbabilityApiInfo>>> odProbabilityApiInfosMapmap,
                                       Map<String, PersonPath> route2PersonPathMap
            , Map<String, List<RouteStation>> t80RouteHisMap,
                                       Map<String, Station> stationNetMap, Map<String, TransferStation> transferStationMap) {

        this.odProbabilityApiInfosMapmap = odProbabilityApiInfosMapmap;
        this.route2PersonPathMap = route2PersonPathMap;
        this.t80RouteHisMap = t80RouteHisMap;
        this.stationNetMap = stationNetMap;
    }


    @Override
    public void LoadPersons(int size, String stationId) {

        Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap=odProbabilityApiInfosMapmap.get(stationId);
        loadHistoryPeriodPersons(size,odProbabilityApiInfosMap, route2PersonPathMap);


    }


    public  void loadHistoryPeriodPersons(int size,
                                          Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                          Map<String, PersonPath> route2PersonPathMap){

        if (odProbabilityApiInfosMap.keySet().size() > size) {
            addPersonsWhenExceedingSize(size, odProbabilityApiInfosMap, route2PersonPathMap);
        }else{
            int infoSize = size / odProbabilityApiInfosMap.size();
            addPersonsBasedOnRouteRates(odProbabilityApiInfosMap, route2PersonPathMap, infoSize);
        }
    }

//    @Override
//    public Map<String, Person> getOutsidePersonMap() {
//        return Collections.emptyMap();
//    }

    private int calculatePersonCount(String routeRate, int infoSize) {
        double num = Double.parseDouble(routeRate) * 0.01 * infoSize;
        return (int) Math.floor(num);
    }


    private void addPersonsBasedOnRouteRates(Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                             Map<String, PersonPath> route2PersonPathMap,
                                             int infoSize){
        for (Map.Entry<String, List<ODProbabilityApiInfo>> entry : odProbabilityApiInfosMap.entrySet()) {
            for (ODProbabilityApiInfo info : entry.getValue()) {
                String routeId = info.getRouteId();
                int result = calculatePersonCount(info.getRouteRate(), infoSize);
                for (int j = 0; j < result; j++) {
                    addPersonForRoute(routeId, route2PersonPathMap);
                }
            }
            addPersonForRoute(entry.getValue().get(0).getRouteId(), route2PersonPathMap);
        }
    }
    private void addPersonForRoute(String routeId, Map<String, PersonPath> route2PersonPathMap) {


        if(route2PersonPathMap.containsKey(routeId)){
            PersonPath personPath = route2PersonPathMap.get(routeId);
            Person person = new Person(personPath);
            person.setId(UUID.randomUUID().toString());
            person.setInStationState();
            this.outsidePersonMap.put(person.getId(), person);
        }



    }

//    private int calculatePersonCount(String routeRate, int infoSize) {
//        double num = Double.parseDouble(routeRate) * 0.01 * infoSize;
//        return (int) Math.floor(num);
//    }


    private void addPersonsWhenExceedingSize(int size,
                                             Map<String, List<ODProbabilityApiInfo>> odProbabilityApiInfosMap,
                                             Map<String, PersonPath> route2PersonPathMap) {
        for (Map.Entry<String, List<ODProbabilityApiInfo>> entry : odProbabilityApiInfosMap.entrySet()) {
            Collections.sort(entry.getValue());
            List<ODProbabilityApiInfo> odProbabilityApiInfoList = entry.getValue();
            addPersonForRoute(odProbabilityApiInfoList,size,route2PersonPathMap);

        }


    }

    private void addPersonForRoute(
            List<ODProbabilityApiInfo> odProbabilityApiInfoList,
            int size,
            Map<String, PersonPath> route2PersonPathMap) {
        int count=0;

        for (int i = 0; i < odProbabilityApiInfoList.size(); i++) {
            String routeId = odProbabilityApiInfoList.get(i).getRouteId();
            if (route2PersonPathMap.containsKey(routeId)) {
//                double count1 = size * Double.parseDouble(odProbabilityApiInfoList.get(i).getRouteRate());
//                int count = (int) Math.floor(count1);

                for (int n = 0; n < size; n++) {
                    PersonPath personPath = route2PersonPathMap.get(routeId);
                    Person person = new Person(personPath);
                    person.setId(UUID.randomUUID().toString());
                    person.setInStationState();
                    this.outsidePersonMap.put(person.getId(), person);
                    count++;
                }
                if(count>=size){
                    return;
                }

            }

        }


    }
}
